#include <util/delay.h>
#include <avr/io.h>
#include <util/twi.h>

void I2CHW_Init()
{
}

char I2CHW_Start()
{
	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA);
	while ( !( TWCR & ( 1 << TWINT ) ) );
	return ( TW_STATUS == TW_START ) || ( TW_STATUS != TW_REP_START );
}

void I2CHW_Stop()
{
	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
}

char I2CHW_Write(unsigned char data)
{
	TWDR = data;
	TWCR = (1 << TWINT) | (1 << TWEN);
	while ( !( TWCR & ( 1 << TWINT ) ) );
	return (TW_STATUS == TW_MT_SLA_ACK) || (TW_STATUS == TW_MT_DATA_ACK );
}

unsigned char I2CHW_Read( unsigned char ackFlag )
{
	if ( ackFlag == 0 )
	{
		TWCR = (1 << TWINT) | (1 << TWEN);
	}
	else
	{
		TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
	}

	while (!(TWCR & (1 << TWINT)));
	if ( (TW_STATUS == TW_MR_DATA_ACK) || (TW_STATUS == TW_MR_DATA_NACK) )
	{
		
	}
	else
	{
	//	err = 0xfe;
	}

	return TWDR;

}


unsigned char WriteLocation( unsigned char i2c_addr, unsigned char *data, unsigned char len )
{
	unsigned char i = 0xff;

	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA);
	while ( !( TWCR & ( 1 << TWINT ) ) );
	if ( TW_STATUS == TW_START )
	{
	    i--;

		// set I2C Address
		TWDR = i2c_addr;
		TWCR = (1 << TWINT) | (1 << TWEN);
		while ( !( TWCR & ( 1 << TWINT ) ) );
		if (TW_STATUS == TW_MT_SLA_ACK)
		{
			for( i= 0; i< len; i++ )
			{
				TWDR = data[i];
				TWCR = (1 << TWINT) | (1 << TWEN);
				while ( !( TWCR & ( 1 << TWINT ) ) );
				if ( TW_STATUS != TW_MT_DATA_ACK )
				{
					break;
				}
			}		
		}
	}

	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
	return i;
}

unsigned char ReadLocation( unsigned char i2c_addr, unsigned char *data, unsigned char len )
{
	unsigned char length = len;

	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA);
	while ( !( TWCR & ( 1 << TWINT ) ) );
	if ( TW_STATUS == TW_START )
	{
		// set I2C Address
		TWDR = i2c_addr | 1;
		TWCR = (1 << TWINT) | (1 << TWEN);
		while ( !( TWCR & ( 1 << TWINT ) ) );
		if (TW_STATUS == TW_MT_SLA_ACK)
		{
			while( length )
			{
				if (length == 1) 
				{
					TWCR = (1 << TWINT) | (1 << TWEN);
					while (!(TWCR & (1 << TWINT)));
					if ( TW_STATUS != TW_MR_DATA_NACK )
					{
						break;
					}
				}
				else
				{
					TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
					while (!(TWCR & (1 << TWINT)));
					if ( TW_STATUS != TW_MR_DATA_ACK )
					{
						break;
					}
				}

				
				*data = TWDR;
				data++;
				length--;
			}		
		}
	}

	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
	return len - length;
}
